package com.dd.cloud.user.service.pres.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.annotate.validation.Ware;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.user.entity.doctor.DoctorDetail;
import com.dd.cloud.user.entity.pres.DrugsModel;
import com.dd.cloud.user.entity.pres.PresBasics;
import com.dd.cloud.user.entity.pres.PresBasicsDrugs;
import com.dd.cloud.user.mapper.pres.DrugsModelMapper;
import com.dd.cloud.user.mapper.pres.PresBasicsMapper;
import com.dd.cloud.user.req.pres.PresBasicDrugReq;
import com.dd.cloud.user.req.pres.PresBasicFrom;
import com.dd.cloud.user.req.pres.UpdatePresBasicFrom;
import com.dd.cloud.user.res.agent.AgentCountChartStatisticsListRes;
import com.dd.cloud.user.res.drugs.DrugsBasicBatchRes;
import com.dd.cloud.user.service.doctor.IDoctorDetailService;
import com.dd.cloud.user.service.pres.IDrugsModelService;
import com.dd.cloud.user.service.pres.IPresBasicsDrugsService;
import com.dd.cloud.user.service.pres.IPresBasicsService;
import com.dd.cloud.user.service.pres.IPresPretrialDrugsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;
import rx.functions.Function;

import javax.print.Doc;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 基础处方库 服务实现类
 * </p>
 *
 * @author czg
 * @since 2023-11-30
 */
@Service
public class PresBasicsServiceImpl extends ServiceImpl<PresBasicsMapper, PresBasics> implements IPresBasicsService {

    @Autowired
    private IDoctorDetailService doctorDetailService;

    @Autowired
    private IPresBasicsDrugsService presBasicsDrugsService;


    @Autowired
    private DrugsModelMapper drugsModelMapper;

    @Override
    public PresBasics queryPresBasicDetails(Integer basicsId) {
        PresBasics presBasics = this.getById(basicsId);
        if (presBasics == null) {
            throw new ZekeException("记录不存在");
        }
        LambdaQueryWrapper<PresBasicsDrugs> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PresBasicsDrugs::getBasicsId, basicsId)
                .eq(PresBasicsDrugs::getStatus, 1)
                .orderByDesc(PresBasicsDrugs::getId);
        List<PresBasicsDrugs> drugsList = presBasicsDrugsService.list(wrapper);
        presBasics.setPresBasicsDrugsList(drugsList);
        return presBasics;
    }

    @Override
    public void addPresBasicDetails(PresBasicFrom from) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        LambdaQueryWrapper<DoctorDetail> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DoctorDetail::getDoctorId, loginInfo.getId());
        DoctorDetail doctorDetail = doctorDetailService.getOne(wrapper);
        String doctorName = "";
        if (doctorDetail != null) {
            doctorName = doctorDetail.getName();
        }
        LambdaQueryWrapper<PresBasics> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PresBasics::getDoctorId, loginInfo.getId())
                .eq(PresBasics::getStatus, 1)
                .orderByAsc(PresBasics::getSort);
        List<PresBasics> presBasicList = this.list(queryWrapper);
//        Integer sort = 1;
//        if (oldPresBasics != null) {
//            sort = oldPresBasics.getSort() + 1;
//        }
        PresBasics presBasics = new PresBasics();
        presBasics.setName(from.getName())
                .setStatus(1)
                .setRemark(from.getRemark())
                .setCreateDate(LocalDateTime.now())
                .setUpdateDate(LocalDateTime.now())
                .setUpdateName(doctorName)
                .setSort(1)
                .setDoctorId(loginInfo.getId());
        boolean flag = this.save(presBasics);
        if (!flag) {
            throw new ZekeException("保存处方失败!");
        }
        Integer basicsId = presBasics.getId();
        List<PresBasicDrugReq> presBasicDrugReqList = from.getPresBasicDrugReqList();
        List<PresBasicsDrugs> drugsList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(presBasicDrugReqList)) {
            presBasicDrugReqList.forEach(item -> {
                PresBasicsDrugs presBasicsDrugs = new PresBasicsDrugs();
                presBasicsDrugs.setBasicsId(basicsId)
                        .setDrugName(item.getDrugName())
                        .setDecocting(item.getDecocting())
                        .setUseUint(item.getUseUint())
                        .setCreateDate(LocalDateTime.now())
                        .setStatus(1);
                drugsList.add(presBasicsDrugs);
            });
        }
        if (CollectionUtil.isNotEmpty(drugsList)) {
            boolean flag1 = presBasicsDrugsService.saveBatch(drugsList);
            if (!flag1) {
                throw new ZekeException("保存药品失败!");
            }
        }
        if (CollectionUtil.isNotEmpty(presBasicList)) {
            presBasicList.stream().forEach(item -> {
                item.setSort(item.getSort() + 1);
            });
            boolean flag2  = this.updateBatchById(presBasicList);
            if(!flag2){
                throw new ZekeException("更新数据失败!");
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePresBasic(UpdatePresBasicFrom from) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        LambdaQueryWrapper<DoctorDetail> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DoctorDetail::getDoctorId, loginInfo.getId());
        DoctorDetail doctorDetail = doctorDetailService.getOne(wrapper);
        String doctorName = "";
        if (doctorDetail != null) {
            doctorName = doctorDetail.getName();
        }
        Integer basicsId = from.getBasicsId();
        PresBasics presBasics = this.getById(basicsId);
        if (presBasics == null) {
            throw new ZekeException("记录不存在");
        }
        presBasics.setRemark(from.getRemark())
                .setName(from.getName())
                .setUpdateDate(LocalDateTime.now())
                .setUpdateName(doctorName)
                .setName(from.getName());
        boolean flag = this.updateById(presBasics);
        if (!flag) {
            throw new ZekeException("处方更新失败");
        }
//
//        LambdaQueryWrapper<PresBasicsDrugs> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(PresBasicsDrugs::getStatus, 1)
//                .eq(PresBasicsDrugs::getBasicsId, basicsId);
        //删除
        LambdaUpdateWrapper<PresBasicsDrugs> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(PresBasicsDrugs::getBasicsId, from.getBasicsId())
                .set(PresBasicsDrugs::getStatus, -1);
        presBasicsDrugsService.update(updateWrapper);
        List<PresBasicsDrugs> drugsList = new ArrayList<>();
        List<PresBasicDrugReq> presBasicDrugReqList = from.getPresBasicDrugReqList();
        if (CollectionUtil.isNotEmpty(presBasicDrugReqList)) {
            List<PresBasicDrugReq> addPresBasicDrug = presBasicDrugReqList.stream().filter(item -> item.getDrugId() == null).collect(Collectors.toList());
            List<PresBasicDrugReq> updatePresBasicDrug = presBasicDrugReqList.stream().filter(item -> item.getDrugId() != null).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(addPresBasicDrug)) {
                addPresBasicDrug.stream().forEach(item -> {
                    PresBasicsDrugs presBasicsDrug = new PresBasicsDrugs();
                    presBasicsDrug.setDrugName(item.getDrugName())
                            .setBasicsId(basicsId)
                            .setDecocting(item.getDecocting())
                            .setStatus(1)
                            .setCreateDate(LocalDateTime.now())
                            .setUseUint(item.getUseUint());
                    drugsList.add(presBasicsDrug);
                });
            }
            if (CollectionUtil.isNotEmpty(updatePresBasicDrug)) {
                updatePresBasicDrug.stream().forEach(item -> {
                    PresBasicsDrugs presBasicsDrug = new PresBasicsDrugs();
                    presBasicsDrug.setStatus(1).setId(item.getDrugId());
                    drugsList.add(presBasicsDrug);
                });
            }
        }


        if (CollectionUtil.isNotEmpty(drugsList)) {
            boolean flag1 = presBasicsDrugsService.saveOrUpdateBatch(drugsList);
            if (!flag1) {
                throw new ZekeException("保存药品失败!");
            }
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePresBasicsStatus(Integer basicsId) {
        PresBasics presBasics = this.getById(basicsId);
        if (presBasics == null) {
            throw new ZekeException("~记录不存在~");
        }
        presBasics.setStatus(-1);
        boolean flag = this.updateById(presBasics);
        if (!flag) {
            throw new ZekeException("~删除失败~");
        }
        LambdaUpdateWrapper<PresBasicsDrugs> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(PresBasicsDrugs::getBasicsId, basicsId)
                .set(PresBasicsDrugs::getStatus, -1);
        boolean flag1 = presBasicsDrugsService.update(updateWrapper);
        if (!flag1) {
            throw new ZekeException("~删除失败~");
        }
        Integer sort = presBasics.getSort();
        LambdaQueryWrapper<PresBasics> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PresBasics::getDoctorId, presBasics.getDoctorId()).eq(PresBasics::getStatus, 1)
                .gt(PresBasics::getSort, sort).orderByAsc(PresBasics::getSort);
        List<PresBasics> presBasicsList = this.list(wrapper);
        if (CollectionUtil.isNotEmpty(presBasicsList)) {
            presBasicsList.forEach(item -> {
                item.setSort(item.getSort() - 1);
            });
            boolean flag3 = this.updateBatchById(presBasicsList);
            if (!flag3) {
                throw new ZekeException("~删除失败~");
            }
        }
    }

    @Override
    public void movePresBasics(Integer basicsId, Integer flag) {
        PresBasics presBasics = this.getById(basicsId);
        if (presBasics == null) {
            throw new ZekeException("记录为空");
        }
        LambdaQueryWrapper<PresBasics> wrapper = new LambdaQueryWrapper<>();
        //上移动
        if (flag == 1) {
            wrapper.lt(PresBasics::getSort, presBasics.getSort())
                    .orderByDesc(PresBasics::getSort);
            //下移动
        } else if (flag == 2) {
            wrapper.gt(PresBasics::getSort, presBasics.getSort())
                    .orderByAsc(PresBasics::getSort);
        }
        wrapper.eq(PresBasics::getDoctorId, presBasics.getDoctorId())
                .eq(PresBasics::getStatus, 1)
                .last("limit 1");
        PresBasics oldPresBasics = this.getOne(wrapper);
        Integer oldSort = oldPresBasics.getSort();
        Integer preSort = presBasics.getSort();
        oldPresBasics.setSort(preSort);
        presBasics.setSort(oldSort);
        List<PresBasics> list = new ArrayList<>();
        list.add(oldPresBasics);
        list.add(presBasics);
        if (CollectionUtil.isNotEmpty(list)) {
            boolean flag1 = this.updateBatchById(list);
            if (!flag1) {
                throw new ZekeException("~移动失败~");
            }
        }
    }

    @Override
    public List<DrugsBasicBatchRes> queryDrugsBatch(String drugNames, Integer pharId) {
        if (StringUtils.isBlank(drugNames)) {
            throw new ZekeException("药品不能为空");
        }
        String[] strs = drugNames.split(",");
        List<DrugsBasicBatchRes> drugsBasicBatchResList = new ArrayList<>();
        for (String drugName : strs) {
            DrugsBasicBatchRes drugsBasicBatchRes = new DrugsBasicBatchRes();
            drugsBasicBatchRes.setDrugName(drugName);
            drugsBasicBatchRes.setIsExist(false);
            drugsBasicBatchResList.add(drugsBasicBatchRes);
        }
        List<DrugsModel> drugsModels = drugsModelMapper.queryDrugsBatch(strs, pharId);
        if (CollectionUtil.isNotEmpty(drugsModels)) {
            Map<String, DrugsModel> drugMap = drugsModels.stream().collect(
                    Collectors.toMap(DrugsModel::getHerbName, (p) -> p));
            drugsBasicBatchResList.stream().forEach(item -> {
                DrugsModel drugsModel = drugMap.get(item.getDrugName());
                if (drugsModel != null) {
                    item.setIsExist(true);
                }
            });
        }
        return drugsBasicBatchResList;
    }
}
